#include "IttClient.h"
#include "myd3dutil.h"
#include "Me.h"
#include "myUtil.h"

#include <cmath>

const float IttClient::PI = (float)acos(-1.);

IttClient::IttClient() 
{
	init();
}

IttClient::IttClient(SOCKET s) : m_s(s)
{
	init();
}

IttClient::~IttClient()
{}

int
IttClient::init()
{ 
	m_posx = -5;
	m_posy = -5;
	m_id = 0;
	m_bLoaded = false;
    m_bUDMoving = false;
    m_bLRMoving = false;

	InitializeCriticalSection(&m_cs);
	memset(m_name, 0, sizeof(m_name));

	m_direction = 0;
	m_btnUDDirection = 0;
    m_btnLRDirection = 0;

	m_VB = NULL;
	m_IB = NULL;
    m_NameMesh = NULL;
    m_dx = 0;

	createVertex();
	return 0;
}

int
IttClient::createVertex()
{
	d3dDrawer::Get()->getDevice()->CreateVertexBuffer(
		4*sizeof(Vertex),
		D3DUSAGE_WRITEONLY,
		Vertex::FVF,
		D3DPOOL_MANAGED,
		&m_VB,
		0);
	d3dDrawer::Get()->getDevice()->CreateIndexBuffer(
		12 * sizeof(WORD),
		D3DUSAGE_WRITEONLY,
		D3DFMT_INDEX16,
		D3DPOOL_MANAGED,
		&m_IB,
		0);

	Vertex *v = NULL;
	m_VB->Lock(0, 0, (void**)&v, 0);
	v[0] = Vertex(-1, 0, -0.5);
	v[1] = Vertex(0, 0, 1.5);
	v[2] = Vertex(1, 0, -0.5);
	v[3] = Vertex(0, 1, -0.5);

	for (int i = 0; i < 4; ++ i){
		v[i]._color = D3DCOLOR_XRGB(0, 0, 0);
	}
	m_VB->Unlock();

	WORD *ind = NULL;
	m_IB->Lock(0, 0, (void**)&ind, 0);
	ind[0] = 0; ind[1] = 2; ind[2] = 1;
	ind[3] = 0; ind[4] = 1; ind[5] = 3;
	ind[6] = 0; ind[7] = 3; ind[8] = 2;
	ind[9] = 2; ind[10] = 3; ind[11] = 1;
	m_IB->Unlock();

	return 0;
}

float
IttClient::getX()
{
	return m_posx;
}

float
IttClient::getY()
{
	return m_posy;
}

SOCKET
IttClient::getS()
{
	return m_s;
}

IDirect3DVertexBuffer9*
IttClient::getVB()
{
	return m_VB;
}

IDirect3DIndexBuffer9*
IttClient::getIB()
{
	return m_IB;
}

int
IttClient::setXY(float x, float y)
{
	m_posx = x;
	m_posy = y;
	return 0;
}

int
IttClient::setDirection(float direction)
{
	m_direction = direction;
	return 0;
}

float
IttClient::getDirection()
{
	return m_direction;
}

int
IttClient::setBtnUDDir(unsigned int btnDir)
{
	m_btnUDDirection = btnDir;
	return 0;
}

int
IttClient::setBtnLRDir(unsigned int btnDir)
{
	m_btnLRDirection = btnDir;
	return 0;
}

unsigned int
IttClient::getBtnUDDir()
{
	return m_btnUDDirection;
}

unsigned int
IttClient::getBtnLRDir()
{
	return m_btnLRDirection;
}

bool
IttClient::setUDMoving(bool bMoving)
{
    return m_bUDMoving = bMoving;
}

bool
IttClient::setLRMoving(bool bMoving)
{
    return m_bLRMoving = bMoving;
}

bool
IttClient::getUDMoving()
{
    return m_bUDMoving;
}

bool
IttClient::getLRMoving()
{
    return m_bLRMoving;
}

int
IttClient::setID(unsigned int id)
{
	m_id = id;
	return 0;
}

unsigned int
IttClient::getID()
{
	return m_id;
}

int
IttClient::setName(WCHAR *ws)
{
	wsprintf(m_name, L"%s", ws);

    HDC hdc = ::CreateCompatibleDC(0);
    HFONT hFont;
    HFONT hFontOld;
    LOGFONTW lf;
    ZeroMemory(&lf, sizeof(LOGFONTW));

    lf.lfHeight = 1;
    lf.lfWidth = 1;
    lf.lfEscapement = 0;
    lf.lfOrientation = 0;
    lf.lfWeight = 10;
    lf.lfItalic = false;
    lf.lfUnderline = false;
    lf.lfStrikeOut = false;
    lf.lfCharSet = DEFAULT_CHARSET;
    lf.lfOutPrecision = 0;
    lf.lfClipPrecision = 0;
    lf.lfQuality = 0;
    lf.lfPitchAndFamily = 0;
    wcscpy_s(lf.lfFaceName, L"Times New Roman");

    hFont = ::CreateFontIndirectW(&lf);
    hFontOld = (HFONT)SelectObject(hdc, hFont);
    SelectObject(hdc, (HPEN)GetStockObject(BLACK_PEN));
    
    IDirect3DDevice9 *device = d3dDrawer::Get()->getDevice();
    ::D3DXCreateTextW(device, hdc, m_name, 0.000f, 0.0000001, &m_NameMesh, 0, 0);
    SelectObject(hdc, hFontOld);
    DeleteObject(hFont);
    DeleteDC(hdc);

	return 0;
}

WCHAR *
IttClient::getName()
{
	return m_name;
}

int 
IttClient::draw(IDirect3DDevice9* device, float timeDelta)
{
	D3DXMATRIX transMatrix, Ry;
	D3DXMatrixTranslation(&transMatrix, this->getX(), 0, this->getY());
	D3DXMatrixRotationY(&Ry, this->getDirection());
	Ry *= transMatrix;
	device->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
	device->SetTransform(D3DTS_WORLD, &Ry);
	device->SetStreamSource(0, m_VB, 0, sizeof(Vertex));
	device->SetIndices(m_IB);
	device->SetFVF(Vertex::FVF);
	device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 4, 0, 4);

	lwd3dutil::d3dDrawText(device, m_NameMesh, this->getX(), 0, this->getY(), 3.14/4, Me->getDirection(), 0);
	return 0;
}

int
IttClient::move(float speed)
{
	float tx = this->getX();
	float ty = this->getY();
	float lx = 0;
	float ly = 0;
	float dir = 0;
    speed /= 10;
    if (this->getUDMoving()){
    	switch (this->getBtnUDDir())
    	{
    	case VK_UP:
    		lx = speed * sin(this->getDirection());
    		ly = speed * cos(this->getDirection());
    		tx += lx;
    		ty += ly;
    		break;
    	case VK_DOWN:
    		lx = -speed * sin(this->getDirection());
    		ly = -speed * cos(this->getDirection());
    		tx += lx;
    		ty += ly;
    		break;
    	}
    	this->setXY(tx, ty);
    }
    if (this->getLRMoving()){
        switch (this->getBtnLRDir()) 
        {
        case VK_LEFT:
    		lx = speed * sin(this->getDirection() - PI/2);
    		ly = speed * cos(this->getDirection() - PI/2);
    		tx += lx;
    		ty += ly;
            break;
        case VK_RIGHT:
    		lx = -speed * sin(this->getDirection() - PI/2);
    		ly = -speed * cos(this->getDirection() - PI/2);
    		tx += lx;
    		ty += ly;
        }
        this->setXY(tx, ty);
    }
    int width, height;
    myUtil::getScreenWH(width, height);
    dir = this->getDirection() + PI/180 * this->getDx()/(width/2)*90;
    dir = dir < 0 ? dir + 2*PI : dir;
    this->setDirection(dir);
    this->setDx(0);
	return 0;
}

int
IttClient::speak(WCHAR *sentence)
{
	return 0;
}

int
IttClient::push_back(pttpack ppack)
{
	m_tasklist.push_back(ppack);
	return 0;
}

pttpack
IttClient::getfront()
{
	pttpack ppack = m_tasklist.front();
	m_tasklist.pop_front();
	return ppack;
}

bool
IttClient::isEmpty()
{
	return m_tasklist.empty();
}

int
IttClient::addDx(int dx)
{
    return m_dx += dx;
}

int
IttClient::getDx()
{
    return m_dx;
}

int
IttClient::setDx(int dx)
{
   return m_dx = dx; 
}